-- UIRotineActivity
-- Created by cheny3 Nov/10/2016
-- 常规活动界面

UIRotineActivity = class("UIRotineActivity", function()
    return cc.Layer:create();
end);

function UIRotineActivity.create()
    return UIRotineActivity.new();
end

local sortRules;
local sortTasks;

-- 构造函数
function UIRotineActivity:ctor()
    self:setName("UIRotineActivity");

    -- 初始化（复用迷宫条目界面）
    local node = cc.CSLoader:createNode("layout/main/SubMapList.csb");
    self:addChild(node);
    self.node = node;
    local scrollview = findChildByName(self.node, "TOP/scrollview");
    self.scrollview = scrollview;

    -- 主界面
    self.type = "main";

    self.id = RotineActivityM.getCurRotineActivityId();

    -- 适配
    self:resize();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 注册事件处理回调函数
    self:regiserEventCallback();

    -- 初始化窗口
    self:redraw();

    -- 初始化标示
    self.isInit = true;
end

-- 显示/隐藏底部BUTTON
function UIRotineActivity:showBottomBotton(visible)
    local BT = findChildByName(self.node, "BT");
    BT:setVisible(visible);
end

-- 获得焦点隐藏焦点
function UIRotineActivity:bottomFlyUp()
    local bottom = findChildByName(self.node, "BT");
    if bottom then
        bottom:setVisible(true);
        FormEffectM.btPopUpFromBottom(self);
    end
end

-- 注册事件处理回调函数
function UIRotineActivity:regiserEventCallback()
    -- 注册获得焦点的回调
    EventMgr.register("UIRotineActivity", event.FOCUS_CHANGED, function(para)
        if para["get"] == "UIInvisibleForm" or para["lose"] == "UIInvisibleForm" then
            return;
        end

        -- 非初始化获得焦点，BOTTOM向上
        if para["get"] == "UIRotineActivity" then
            UIMgr:getCurrentScene().topMenu:show(TOPMENU_FRAME_MONEY, TOPMENU_FRAME_ROTINE_ACTIVITY);
            if not self.isInit then
                self:bottomFlyUp();
            end

            self:checkNotify();
        elseif para["lose"] == "UIRotineActivity" then
            -- 失去焦点BOTTOM隐藏
            self:showBottomBotton(false);
        end

        if self.isInit then
            self.isInit = false;
        end
    end);

    -- 注册玩家信息更新的回调
    EventMgr.register("UIRotineActivity", event.USER_INFO_UPDATED, function(args)
        -- 常规活动
        if args == "rotine_activity_info" then
            if self.type ~= "treasure_bonus" then
                if not UIMgr.getCurrentScene():getFormByName("UIRotineShop") then
                    self.noEffect = true;
                    self:redraw();
                    self.noEffect = false;
                end
            end
        end
    end);

    -- 挖宝结果
    EventMgr.register("UIRotineActivity", event.ROTINE_OPEN_TREASURE_RESULT, function(args)
        local result = args.result;
        local index = args.index;

        self:resultArriveFun();

        if self.type == "treasure_bonus" and result == 1 then
            self:whenOpenTreasure(index);
        elseif result == 0 then
            alert(getLocStr("rotine_treasure_fail_tip"));
        end
    end);

    -- 领奖结果
    EventMgr.register("UIRotineActivity", event.ROTINE_TAKE_TREASURE_RESULT, function(args)
        local result = args.result;
        local index = args.index;

        self:resultArriveFun();

        if self.type == "treasure_bonus" and result == 1 then
            self:whenTakeTreasure(index);
        elseif result == 0 then
            alert(getLocStr("rotine_progress_fail_tip"));
        end
    end);

    -- 领奖结果
    EventMgr.register("UIRotineActivity", event.ROTINE_PROGRESS_BONUS_RESULT, function(args)
        local result = args.result;
        local bonus = args.bonus;

        self:resultArriveFun();

        if self.type == "main" or self.type == "treasure_bonus" then
            return;
        end

        if result == 0 then
            alert(getLocStr("rotine_progress_fail_tip"));
        else
            local taskId = RotineActivityM.getAllTasksByRule(self.type)[1];
            local title = RotineActivityM.queryTask(taskId, "name");
            showBonusNotifyForm(title, {{ "rotine", bonus[1], bonus[2]},});
        end
    end);

    -- 关注活动结束
    EventMgr.register("UIRotineActivity", event.ACTIVITY_CLOSE, function(args)
        if RotineActivityM.isInRotineActivity() then
            return;
        end

        -- 关闭界面
        UIMgr.getCurrentScene():removeFormByName("UIRotineActivity");
        UIMgr.getCurrentScene():removeFormByName("UIRotineShop");
        UIMgr.getCurrentScene():removeFormByName("UIShowTip");
        UIMgr.getCurrentScene():removeFormByName("UIRotineShopDetail");
    end);

    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            cclog("UIRotineActivity 界面析构清理");
            EventMgr.removeAll("UIRotineActivity");
        end
    end);
end

-- 注册点击事件
function UIRotineActivity:registerTouchEvent()
    local TOP = findChildByName(self.node, "TOP");
    local BT = findChildByName(self.node, "BT");

    -- 注册返回按钮点击事件
    local btnBack = findChildByName(BT, "btn_back");
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_return");
            if self.type == "main" then
                closeFormByName("UIRotineActivity");
            else
                self.type = "main";
                self:redraw();
                self:bottomFlyUp();
            end
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);

    -- 注册招募按钮点击事件
    local btnRecruit = findChildByName(BT, "btn_dungeon");
    TextStyleM.setTextStyle(btnRecruit, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnRecruit:setTitleText(getLocStr("btn_text_recruit2"));
    local function onRecruitClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");

            if self.type == "main" then
                -- 说明按钮
                local rotineType = RotineActivityM.getRotineInfo()["rotine_type"];
                local title = getLocStr("rotine_title_" .. rotineType);
                local content = getLocStr("rotine_desc_" .. rotineType);
                showActivityTip(title, content);
            else
                self:waitResultFun();

                -- 领奖按钮
                RotineActivityM.takeProgerssBonus(self.type);
            end
        end
    end
    btnRecruit:addTouchEventListener(onRecruitClick);
end

-- 检查按钮
function UIRotineActivity:redrawBtn()
    local btnRecruit = findChildByName(self.node, "BT/btn_dungeon");
    btnRecruit:setVisible(true);

    local tip = false;
    if self.type == "main" then
        -- 主界面显示说明按钮
        btnRecruit:setTitleText(getLocStr("btn_text_help"));
        btnRecruit:setTouchEnabled(true);
        btnRecruit:setBright(true);
    elseif self.type == "treasure_bonus" then
        -- 挖宝界面
        btnRecruit:setVisible(false);
    else
        -- 子界面显示领取按钮
        btnRecruit:setTitleText(getLocStr("btn_text_take_bonus"));

        if RotineActivityM.canTakeProgressBonus(self.type) then
            -- 进度奖励
            tip = true;
            btnRecruit:setTouchEnabled(true);
            btnRecruit:setBright(true);
        else
            btnRecruit:setTouchEnabled(false);
            btnRecruit:setBright(false);
        end
    end

    -- 如果需要有提示
    local hintImg = findChildByName(btnRecruit, "hint");
    if tip then
        hintImg:setVisible(true);
        checkBlueBubbleStatus(hintImg, true);
    else
        hintImg:setVisible(false);
    end
end

-- 检查气泡
function UIRotineActivity:checkNotify()
    local bubbleNode = findChildByName(self.node, "TOP/image/bubble_node");
    bubbleNode:setPosition(cc.p(320,132));
    if RotineActivityM.canBonus() then
        bubbleNode:setVisible(true);
        bubbleNode:stopAllActions();
        playBubbleAnima(bubbleNode, false, 0.9);
    else
        bubbleNode:setVisible(false);
    end
end

-- 重绘
function UIRotineActivity:redraw()
    local BT = findChildByName(self.node, "BT");

    -- 设置标题
    local TOP = findChildByName(self.node, "TOP");
    local titleLabel = findChildByName(TOP, "title_bg/text");
    TextStyleM.setOutlineStyle(titleLabel, 1, TextStyleM.TEXT_OUTLINE_COLOR, true);

    -- 图片节点
    local imageIcon = findChildByName(TOP, "image");
    imageIcon:setVisible(false);
    imageIcon:setPositionY(-760);

    -- 挖宝节点
    local rotineBonus = findChildByName(TOP, "rotine_bonus");
    rotineBonus:setVisible(false);

    local rotineType = RotineActivityM.getRotineInfo()["rotine_type"];
    local name = getLocStr("rotine_title_" .. rotineType);
    self.scrollview:setVisible(true);
    self.scrollview:setTouchEnabled(true);

    if self.type == "main" then
        -- 主界面
        imageIcon:setVisible(true);
        imageIcon:loadTexture(getRotineIconPath(rotineType));
        -- 图片点击事件
        self:imageClickEvent();
        self.scrollview:setTouchEnabled(false);
        self:checkNotify();
    elseif self.type == "treasure_bonus" then
        -- 挖宝界面
        self:redrawTreasureBonus();
        self.scrollview:setVisible(false);
    else
        -- 子界面
        local taskId = RotineActivityM.getAllTasksByRule(self.type)[1];
        name = RotineActivityM.queryTask(taskId, "name");
    end

    titleLabel:setString(name);
    TextStyleM.setArtWordTitleStyle(titleLabel);

    -- 显示活动剩余时间
    local remainTimeLabel = findChildByName(TOP, "title_bg/remain_time");
    remainTimeLabel:setVisible(true);
    self.remainTimeLabel = remainTimeLabel;
    if not self.tick then
        self.tick = true;
        self:updateRemainTime();
    end

    -- 显示任务列表
    if self.type ~= "treasure_bonus" then
        self:showTaskList();
    end

    -- 隐藏不相关的按钮
    local btnLeaderboard = findChildByName(self.node, "BT/leaderboard");
    btnLeaderboard:setVisible(false);

    -- 重绘按钮
    self:redrawBtn();
end

-- 图片点击事件
function UIRotineActivity:imageClickEvent()
    local imageNode = findChildByName(self.node, "TOP/image");

    imageNode:setTouchEnabled(true);
    -- 注册按钮点击事件
    AddTouchEventListener(imageNode, function (sender, eventType)
        local rotineType = RotineActivityM.getRotineInfo()["rotine_type"];
        if eventType == ccui.TouchEventType.began then
            -- 1.变小
            local downTime  = 0.25/2;
            local scaleDown = cc.ScaleTo:create(downTime, 0.95);
            imageNode:runAction(scaleDown);
        elseif eventType == ccui.TouchEventType.ended then
            -- 2.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, 1);
            imageNode:runAction(scaleUp);
        elseif eventType == ccui.TouchEventType.canceled then
            -- 3.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, 1);
            imageNode:runAction(scaleUp);
        end

        if eventType == ccui.TouchEventType.ended then
            if rotineType == "treasure" then
                -- 打开宝藏界面
                self.type = "treasure_bonus";
                self:redraw();
                self:bottomFlyUp();
            else
                -- 打开兑换界面
                require "game/ui/form/activity/UIRotineShop"
                UIMgr:getCurrentScene():removeFormByName("UIRotineShop");
                local uiRotineShop = UIRotineShop.create();
                UIMgr:getCurrentScene():addForm(uiRotineShop);
            end
        end
    end);
end

local COVER_STYLE = "grass";
local COVER_NUM = 4;

-- 获取覆盖层资源
function UIRotineActivity:getCoverPath(pos)
    local prefix = "images/cover/" .. COVER_STYLE .. "/";
    local centerNum = DungeonAreaM.queryCover(COVER_STYLE, "centers");

    local path = "";
    if pos == 1 then
        path = "edge/" .. "left_top.png";
    elseif pos == 4 then
        path = "edge/" .. "right_top.png";
    elseif pos == 13 then
        path = "edge/" .. "left_bottom.png";
    elseif pos == 16 then
        path = "edge/" .. "right_bottom.png";
    elseif math.ceil(pos / COVER_NUM) == 1 then
        path = "edge/" .. "top.png";
    elseif math.ceil(pos / COVER_NUM) == COVER_NUM then
        path = "edge/" .. "bottom.png";
    elseif pos % COVER_NUM == 1 then
        path = "edge/" .. "left.png";
    elseif pos % COVER_NUM == 0 then
        path = "edge/" .. "right.png";
    elseif pos == 6 then
        path = "center/4.png";
    elseif pos == 7 then
        path = "center/5.png";
    elseif pos == 10 then
        path = "center/2.png";
    elseif pos == 11 then
        path = "center/3.png";
    else
        -- 从center中随机一个
        if centerNum ~= 0 then
            local r = math.random(1, centerNum);
            path = "center/" .. r .. ".png";
        end
    end

    if path ~= "" then
        path = prefix .. path;
    end

    return path;
end

-- 对应的奖励图标
function UIRotineActivity:getBonusIcon(bonus)
    local iconPath;
    if bonus[1] == 1 then
        iconPath = getItemIconPath(ItemM.query(bonus[2], "icon"));
    elseif bonus[1] == 2 then
        iconPath = getLevelItemIconPath(FieldsM.query(bonus[2], "icon"));
    end

    return iconPath;
end

-- 获取装饰图标
function UIRotineActivity:getDecorateIcon(index)
    if index == 4 then
        return "images/cover/" .. COVER_STYLE .. "/decorate/small/4.png";
    elseif index == 13 then
        return "images/cover/" .. COVER_STYLE .. "/decorate/small/3.png";
    end
    return nil;
end

-- 宝藏物品动画
function UIRotineActivity:treasureItemEffect(image)
    itemMoveEffect(image);
    shiningEffect(image, 50, 50);

    if image.shadow then
        image:getParent():removeChild(image.shadow);
        image.shadow = nil;
    end

    local shadow = ccui.ImageView:create(getLevelItemIconPath("shadow"));
    image:getParent():addChild(shadow);
    image.shadow = shadow;
    shadow:setPosition(cc.p(image:getPositionX(), image:getPositionY() + 10));
    shadow:setLocalZOrder(-1);
    shadow:setScale(1.0);
end

-- 绘制挖宝界面
function UIRotineActivity:redrawTreasureBonus()
    cc.SpriteFrameCache:getInstance():addSpriteFrames("images/cover/" .. COVER_STYLE .. ".plist");

    local TOP = findChildByName(self.node, "TOP");
    local rotineBonus = findChildByName(TOP, "rotine_bonus");
    local panel = findChildByName(rotineBonus, "panel");
    local floor = findChildByName(rotineBonus, "floor");
    panel:removeAllChildren();
    rotineBonus:setVisible(true);
    floor:setPosition(cc.p(7, -555));

    local gridWidth = GRID_WIDTH;
    local gridHeight = GRID_HEIGHT;
    local totalHeight = gridHeight * COVER_NUM;

    -- 4行4列
    for i = 1, COVER_NUM do
        for j = 1, COVER_NUM do
            local index = (i - 1) * COVER_NUM + j;
            local iconPath = self:getCoverPath(index);
            local loadType = 1;

            repeat
                if RotineActivityM.isTreasureTaked(index) then
                    -- 已经领过了，不需要
                    break;
                end

                if RotineActivityM.isTreasureOpened(index) then
                    loadType = 0;
                    -- 已经翻开了，对应奖励图标
                    local bonus = RotineActivityM.getTreasureBonus(index);
                    iconPath = self:getBonusIcon(bonus);
                end

                local image = ccui.ImageView:create(iconPath, loadType);
                local x = (j-1)*gridWidth + gridWidth / 2;
                local y = totalHeight - (i - 1) * gridHeight + GRID_OFFSET_Y - 160;
                image:setPosition(x, y);
                panel:addChild(image);


                if RotineActivityM.isTreasureOpened(index) then
                    self:treasureItemEffect(image);
                    image.iconPath = iconPath;
                else
                    image:stopAllActions();
                end

                image:setName("child_" .. index);
                image.index = index;

                if table.indexOf({1, 4, 13, 16}, index) < 0 and not RotineActivityM.isTreasureOpened(index) then
                    local cover = ccui.ImageView:create(getRotineIconPath(index));
                    image:addChild(cover);
                    cover:setPosition(GRID_WIDTH / 2, GRID_HEIGHT / 2 + 15);
                end

                if not RotineActivityM.isTreasureOpened(index) then
                    -- 加银框
                    local frame = ccui.ImageView:create();
                    frame:loadTexture("images/cover/" .. COVER_STYLE .. "/yingkuang.png", 1);
                    image:addChild(frame);
                    frame:setPosition(GRID_WIDTH / 2 - 2, - GRID_HEIGHT / 2 + 65);

                    -- 加装饰
                    local smallIconPath = self:getDecorateIcon(index);
                    if smallIconPath then
                        local small = ccui.ImageView:create();
                        small:loadTexture(smallIconPath, 1);
                        image:addChild(small);
                        small:setPosition(GRID_WIDTH / 2, GRID_HEIGHT / 2);
                        if index == 4 then
                            small:setPosition(GRID_WIDTH / 2 + 30, GRID_HEIGHT / 2 - 40);
                        end
                    end
                end

                self:registerTreasureClick(image);
            until true
        end
    end

    self:imageAppearEffect(panel);
    self:imageAppearEffect(floor);
end

-- 当玩家开启了宝藏
function UIRotineActivity:whenOpenTreasure(index)
    local rotineBonus = findChildByName(self.node, "TOP/rotine_bonus");
    local panel = findChildByName(rotineBonus, "panel");

    local name = "child_" .. index;
    local child = findChildByName(panel, name);

    if child then
        child:removeAllChildren();
        local bonus = RotineActivityM.getTreasureBonus(index);
        -- 换图标，开格特效
        local iconPath = self:getBonusIcon(bonus);
        child:loadTexture(iconPath);
        child.iconPath = iconPath;
        self:treasureItemEffect(child);
        playEffect(child, 1172, GRID_WIDTH/2 - 10, GRID_HEIGHT/2 - 25);
    end
end

-- 当玩家领取了宝藏
function UIRotineActivity:whenTakeTreasure(index)
    local rotineBonus = findChildByName(self.node, "TOP/rotine_bonus");
    local panel = findChildByName(rotineBonus, "panel");

    local name = "child_" .. index;
    local child = findChildByName(panel, name);

    if child then
        child:removeAllChildren();
        child:setVisible(false);

        if child.shadow then
            child:getParent():removeChild(child.shadow);
        end

        local heroNode = UIMgr.getCurrentScene().topMenu:getHeroNode();
        pickupTreasureEffect(child, heroNode, child.iconPath);

        local function delay()
            -- 通用奖励提示框
            UIMgr.getCurrentScene():removeFormByName("UIBonusNotify");
            local bonus = RotineActivityM.getTreasureBonus(index);
            showBonusNotifyForm(getLocStr("rotine_title_treasure"), {bonus,});
        end
        performWithDelay(self.node, delay, 0.5);
    end
end

-- 宝藏点击
function UIRotineActivity:registerTreasureClick(node)
    local index = node.index;
    node:setTouchEnabled(true);

    -- 注册按钮点击事件
    AddTouchEventListener(node, function (sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            if RotineActivityM.isTreasureTaked(node.index) then
                -- 已经领取过了
            elseif RotineActivityM.isTreasureOpened(node.index) then
                -- 已经翻开过了
                local ret = RotineActivityM.canUserTakeTreasure(node.index);
                if ret ~= true then
                    return;
                end

                self:waitResultFun();

                RotineActivityM.takeTreasure(node.index);
            else
                -- 还未翻开
                local ret = RotineActivityM.canUserOpenTreasure(node.index);
                if true ~= ret then
                    if ret == "lack_item" then
                        alert(getLocStr("rotine_treasure_lack_item"));
                    end
                    return;
                end

                self:waitResultFun();

                RotineActivityM.openTreasure(node.index);
            end
        end
    end);
end

-- 类型类排序
local sortRules = function(a, b)
    local taskId1 = RotineActivityM.getAllTasksByRule(a)[1];
    local taskId2 = RotineActivityM.getAllTasksByRule(b)[1];
    local taskType1 = RotineActivityM.queryTask(taskId1, "type");
    local taskType2 = RotineActivityM.queryTask(taskId2, "type");
    local arr = {"time", "cost", "special", "recharge"};
    return table.indexOf(arr, taskType1) > table.indexOf(arr, taskType2);
end

-- 任务排序
local sortTasks = function(a, b)
    return a > b;
end

-- 显示任务列表
function UIRotineActivity:showTaskList()
    local scrollview = self.scrollview;
    scrollview:removeAllChildren();

    local taskInfo;
    local tasks = {};
    if self.type == "main" then
        -- 主任务列表
        taskInfo = table.deepcopy(RotineActivityM.getUserRotineInfo()["rotine_tasks"] or {});

        for _, taskRule in pairs(table.keys(taskInfo)) do
            if RotineActivityM.canUserShowTask(taskRule) then
                -- 允许显示的
                table.insert(tasks, taskRule);
            end
        end

        table.sort(tasks, sortRules);
    else
        -- 子任务列表
        tasks = table.deepcopy(RotineActivityM.getAllTasksByRule(self.type) or {});

        table.sort(tasks, sortTasks);
    end

    -- 左边距
    local leftMargin = 306;

    -- 行间距
    local gap = 15;
    local widgetHeight = 107;

    -- 任务个数
    local totalNum = #tasks;

    local startHeight = 108 / 2;

    -- 计算总高度
    local totalHeight = totalNum * (widgetHeight + gap);
    if totalHeight < self.originScrollviewHeight then
        startHeight = self.originScrollviewHeight - totalHeight + 108 / 2;
    end

    scrollview:setInnerContainerSize(cc.size(scrollview:getInnerContainerSize().width,
        math.max(totalHeight, self.originScrollviewHeight)));

    local i = 0;
    self.items = {};
    for _, taskRule in ipairs(tasks) do
        local child = cc.CSLoader:createNode("layout/main/RotineActivityItem.csb");
        local x = leftMargin;
        local y = startHeight + i * (widgetHeight + gap);
        child:setPositionX(x);
        child:setPositionY(y);

        table.insert(self.items, child);

        -- 初始化
        if self.type == "main" then
            taskInfo[taskRule]["rule"] = taskRule;
            self:initSubItem(child, taskInfo[taskRule]);
        else
            self:initSubItem2(child, RotineActivityM.queryTask(taskRule));
        end

        scrollview:addChild(child);
        i = i + 1;
    end

    -- 播放飞入效果
    local list = {};
    for i = #self.items, 1, -1 do
        table.insert(list, self.items[i]);
    end

    if not self.noEffect then
        commonScrollItemFlyIn(list);

        local imageNode = findChildByName(self.node, "TOP/image");
        self:imageAppearEffect(imageNode);
    end

    -- 默认滑到最顶端
    if self.type == "main" then
        scrollview:scrollToTop(0.1, true);
    else
        local finishInfo =RotineActivityM.getUserTaskInfo(self.type);
        self:jumpTo(finishInfo);
    end
end

-- 图片弹出效果
function UIRotineActivity:imageAppearEffect(node)
    if self.type ~= "main" and self.type ~= "treasure_bonus" then
        return;
    end

    node.oriScale = node:getScaleY();
    node:stopAllActions();

    node:setScale(0);
    local scaleUp = cc.ScaleTo:create(0.3, node.oriScale * 1.1);
    local scaleDown = cc.ScaleTo:create(0.1, node.oriScale);
    node:runAction(cc.Sequence:create(scaleUp, scaleDown));
end

-- 显示活动剩余时间
function UIRotineActivity:updateRemainTime()
    local remainTime = ActivityM.getRemainTime(self.id);
    local timeDesc = remainingTimeDesc2(remainTime);
    local remainTimeLabel = self.remainTimeLabel;
    TextStyleM.setOutlineStyle(remainTimeLabel, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);
    TextStyleM.setTextStyle(remainTimeLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_LIGHT_YELLOW);
    self.remainTimeLabel = applyString(remainTimeLabel, timeDesc);

    -- 如果还有剩余，每秒刷新一次
    if remainTime > 0 then
        local function callback()
            remainTime = ActivityM.getRemainTime(self.id);
            self:updateRemainTime(remainTime);
        end
        performWithDelay(self.node, callback, 1.0);
    else
        -- 活动结束了，关掉页面
        UIMgr.getCurrentScene():removeFormByName("UIRotineActivity");
    end
end

-- 设置图标和背景为灰色
function UIRotineActivity:setGray(node)
    local bg = findChildByName(node, "bg");
    local bg2 = findChildByName(node, "bg2");
    local bgBar = findChildByName(node, "bg_bar");
    local taskIcon = findChildByName(node, "task_icon");
    local taskBg = findChildByName(node, "task_bg");
    local icon = findChildByName(node, "bonus_node/icon");
    local frame = findChildByName(node, "bonus_node/bg");
    local numLabel = findChildByName(node, "bonus_node/num_label");
    local titleLabel = findChildByName(node, "title");
    local descLabel = findChildByName(node, "desc");
    local nodeArr = {bg, bg2, icon, frame, taskIcon, taskBg};
    for _, setNode in ipairs(nodeArr) do
        setGrayTransMode(setNode, true);
    end

    numLabel:setVisible(false);
    TextStyleM.resetTextStyle(descLabel);
    descLabel.olSize = nil;
    TextStyleM.setTextStyle(descLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_DARK_BROWN, false, -1);
end

-- 初始化三级界面项
function UIRotineActivity:initSubItem2(child, info)
    child.info = info;

    -- 完成信息
    local taskRule = info["rule"];
    local finishInfo = RotineActivityM.getUserTaskInfo(taskRule);

    -- 任务图标
    local taskIcon = findChildByName(child, "task_icon");
    taskIcon:loadTexture(getRotineIconPath(info["task_icon"]));
    self:fixTaskIcon(taskIcon, info["dbase"]);

    -- 任务详细描述
    local titleText = info["title"];
    local nameLabel = findChildByName(child, "title");
    TextStyleM.setTextStyle(nameLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_ORANGE, true, -3, 1.2, nil, nil, nil, true);
    nameLabel:setString(titleText);
    TextStyleM.setOutlineStyle(nameLabel, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);

    -- 完成描述
    local curValue = math.min(finishInfo["value"], info["require"]);
    local taskDesc = string.format(getLocStr("attrib_value_format"), curValue, info["require"]);
    taskDesc = string.gsub(info["task_detail"], "{num}", taskDesc);
    local descLabel = findChildByName(child, "desc");
    TextStyleM.setTextStyle(descLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_LIGHT_BLUE, true, -2, 1.2, nil, nil, nil, true);
    descLabel:setString(taskDesc);
    TextStyleM.setOutlineStyle(descLabel, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);

    -- 右边节点选择
    local bonusNode = findChildByName(child, "bonus_node");
    bonusNode:setVisible(true);
    local itemNode = findChildByName(child, "item_node");
    itemNode:setVisible(false);

    -- 奖励图标
    local allBonus = RotineActivityM.getTaskBonusCount(info["id"]);
    local icon = findChildByName(child, "bonus_node/icon");
    local rotineType = RotineActivityM.getRotineInfo()["rotine_type"];
    local iconPath = info["icon"][rotineType];
    icon:setVisible(true);
    icon:loadTexture(getRotineIconPath(iconPath));

    -- 数量
    local numLabel = findChildByName(child, "bonus_node/num_label");
    TextStyleM.setTextStyle(numLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -3, nil, nil, nil, nil, true);
    TextStyleM.setShadowStyle(numLabel, cc.size(-0.3, -2.8), TextStyleM.TEXT_COLOR_YELLOW_BROWN);
    TextStyleM.setOutlineStyle(numLabel, 1, TextStyleM.TEXT_OUTLINE_COLOR, true);
    numLabel:setString(allBonus[2]);

    if allBonus[2] > 1 then
        numLabel:setVisible(true);
    else
        numLabel:setVisible(false);
    end

    -- 奖励提示
    local tip = findChildByName(child, "tip");
    tip:setVisible(false);

    -- 蒙版
    local mask = findChildByName(child, "mask");
    mask:setVisible(false);
    mask:setOpacity(100);

    if finishInfo["bonusProgress"] >= info["progress"] then
        -- 已经领取了
        -- 变灰白色
        self:setGray(child);
        descLabel:setString(getLocStr("awards_have_received"));
        nameLabel:setString(titleText);
        numLabel:setString(string.format(getLocStr("amount_format"), allBonus[2]));
        mask:setVisible(true);
    elseif curValue >= info["require"] then
        -- 完成了
        playBubbleAnima(tip, false, 1);
        tip:setVisible(true);
        mask:setVisible(false);
    else
        -- 未完成
        mask:setVisible(true);
    end

    -- 背景色/可以点击
    local bg = findChildByName(child, "bg");
    local bg2 = findChildByName(child, "bg2");
    bg:setTouchEnabled(true);
    setGrayMode(bg, false);
    setGrayMode(bg2, false);

    -- 注册按钮点击事件
    bg:setTouchEnabled(false);
    AddTouchEventListener(bg, function (sender, eventType)
        -- TODO
    end);

    -- 注册奖励框点击
    local frame = findChildByName(child, "bonus_node/bg");
    AddTouchEventListener(frame, function(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            local bonus = info["bonus"][rotineType];
            showBonusDesc({"rotine", bonus[1], bonus[2]});
        end
    end);
end

-- 初始化二级页面项
function UIRotineActivity:initSubItem(child, info)
    child.info = info;

    local taskRule = info["rule"];
    local value = info["value"];
    local bonusProgress = info["bonus_progress"];
    local finishInfo = RotineActivityM.getUserTaskInfo(taskRule);

    -- 任务信息
    local taskId = RotineActivityM.getAllTasksByRule(taskRule)[1];
    local taskInfo = RotineActivityM.queryTask(taskId);

    -- 任务图标
    local taskIcon = findChildByName(child, "task_icon");
    taskIcon:loadTexture(getRotineIconPath(taskInfo["task_icon"]));
    self:fixTaskIcon(taskIcon, RotineActivityM.queryTask(taskId, "dbase"));

    -- 任务名字拼上进度
    local name = taskInfo["name"];
    local curProgress = finishInfo["curProgress"];
    local totalProgress = finishInfo["totalProgress"];
    local titleText = string.format(getLocStr("rotine_task_title"), name, curProgress, totalProgress);

    local nameLabel = findChildByName(child, "title");
    TextStyleM.setTextStyle(nameLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_ORANGE, true, -3, 1.2, nil, nil, nil, true);
    nameLabel:setString(titleText);
    TextStyleM.setOutlineStyle(nameLabel, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);

    -- 任务描述
    local bonusDesc = taskInfo["task_desc"];
    local descLabel = findChildByName(child, "desc");
    TextStyleM.setTextStyle(descLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_LIGHT_BLUE, true, -2, 1.2, nil, nil, nil, true);
    descLabel:setString(bonusDesc);
    TextStyleM.setOutlineStyle(descLabel, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);

    -- 右边节点选择
    local bonusNode = findChildByName(child, "bonus_node");
    bonusNode:setVisible(false);
    local itemNode = findChildByName(child, "item_node");
    itemNode:setVisible(true);

    -- 奖励统计
    local allBonus = RotineActivityM.getTotalBonusCount(taskRule);

    -- 奖励图标
    local icon = findChildByName(child, "item_node/icon");
    local rotineType = RotineActivityM.getRotineInfo()["rotine_type"];

    local iconPath = taskInfo["icon"][rotineType];
    icon:setVisible(true);
    icon:loadTexture(getRotineIconPath(iconPath));

    -- 数量标签
    local numLabel = findChildByName(child, "item_node/num");
    TextStyleM.setTextStyle(numLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_LIGHT_BLUE, true, nil, 1.2, nil, nil, nil, true);
    numLabel:setString(string.format(getLocStr("amount_format"), allBonus[2]));
    TextStyleM.setOutlineStyle(numLabel, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);

    -- 因为图标的原因调整一下位置
    if iconPath == "token" then
        icon:setPositionX(183);
        numLabel:setPositionX(240);
    else
        icon:setPositionX(195);
        numLabel:setPositionX(230);
    end

    -- 背景色/可以点击
    local bg = findChildByName(child, "bg");
    local bg2 = findChildByName(child, "bg2");
    bg:setTouchEnabled(true);
    setGrayMode(bg, false);
    setGrayMode(bg2, false);

    -- 提示信息
    local tip = findChildByName(child, "tip");
    tip:setVisible(false);
    if RotineActivityM.canTakeProgressBonus(taskRule) then
        playBubbleAnima(tip, false, 1);
        tip:setVisible(true);
    end

    -- 注册按钮点击事件
    bg:setTouchEnabled(true);
    AddTouchEventListener(bg, function (sender, eventType)
        if eventType == ccui.TouchEventType.began then
            -- 1.变小
            local downTime  = 0.25/2;
            local scaleDown = cc.ScaleTo:create(downTime, 0.95);
            child:runAction(scaleDown);
        elseif eventType == ccui.TouchEventType.ended then
            -- 2.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, 1);
            child:runAction(scaleUp);
        elseif eventType == ccui.TouchEventType.canceled then
            -- 3.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, 1);
            child:runAction(scaleUp);
        end

        if eventType == ccui.TouchEventType.ended then
            -- 进入三级界面
            self.type = taskRule;
            self:redraw();
        end
    end);
end

-- 图标修正
function UIRotineActivity:fixTaskIcon(iconNode, info)
    if type(info) ~= "table" then
        return;
    end

    local scale = info["icon_scale"] or 1;
    local pos = info["icon_pos"] or {-222, 0};
    iconNode:setScale(scale);
    iconNode:setPosition(cc.p(pos[1], pos[2]));
end

-- 结果到达
function UIRotineActivity:resultArriveFun()
    self.waitResult = false;
    UIMgr.getCurrentScene():removeFormByName("UIInvisibleForm");
    closeCommunicatingForm();
end

-- 等待结果
function UIRotineActivity:waitResultFun()
    self.waitResult = true;
    wait(1);
    local function delay()
        if self.waitResult then
            -- 结果还没到，显示加载中
            showCommunicatingForm(getLocStr("loading"));

            local function cancel()
                if self.waitResult then
                    self:resultArriveFun();
                    alert(getLocStr("operation_illage"));
                end
            end
            performWithDelay(self.node, cancel, 10);
        end
    end
    performWithDelay(self.node, delay , 1);
end

-- 移动中心
function UIRotineActivity:jumpTo(finishInfo)
    local bonusProgress = finishInfo["bonusProgress"]
    local totalCount = finishInfo["totalProgress"];

    local scrollview = self.scrollview;
    local percent = 100 - (bonusProgress + 1) * 100 / totalCount;
    if percent < 0 then
        percent = 0;
    end
    scrollview:jumpToPercentVertical(percent);
end

-- 适配
function UIRotineActivity:resize()
    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;

    local scale = w / DESIGN_WIDTH;

    -- 设置scroll的新视口高度
    local scrollview = findChildByName(self.node, "TOP/scrollview");
    local scrollViewSize = scrollview:getContentSize();

    local height = (h / scale) - 420;
    scrollview:setContentSize(scrollViewSize.width, height);

    -- 保存窗口适配后的原始高度
    self.originScrollviewHeight = height;

    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");
    AlignM.fitToScreen(node, "bg2");

    -- TOP置于顶部中间并缩放至合适大小
    AlignM.alignToTopCenter(node, "TOP");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end





